package gui;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;

import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.MaskFormatter;

import java.awt.GridBagLayout;

import javax.swing.JLabel;

import java.awt.GridBagConstraints;

import javax.swing.JTextField;

import net.sourceforge.jdatepicker.impl.JDatePanelImpl;
import net.sourceforge.jdatepicker.impl.JDatePickerImpl;
import net.sourceforge.jdatepicker.impl.UtilCalendarModel;

import java.awt.Insets;
import java.util.ArrayList;
import java.util.Calendar;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JButton;

import business.BusinessImpl;
import dto.DTOClass;
import dto.DTOCompany;
import dto.DTOContact;
import dto.DTORelation;

import javax.swing.JTable;
import javax.swing.JCheckBox;
import javax.swing.SwingConstants;

import constant.Constant;

import javax.swing.JComboBox;

import com.sun.media.jfxmedia.events.NewFrameEvent;

/**
 * @author Jonathan Maret Class used to manage contact
 * 
 */
public class ContactManaging extends JDialog implements ActionListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private BusinessImpl businessImpl = new BusinessImpl();
	private DTOContact selectedContact;
	private JDatePickerImpl datePicker;
	private UtilCalendarModel model;
	private JCheckBox ckbxTypeOfcontact;
	private JLabel lblTypeofContact;
	// the birthdate of the contact
	private Calendar birthdate;
	private JLabel lblCheck;
	private JLabel lblsuccess;
	private JComboBox<?> cbxCompany;
	private boolean visaHasBeenSetByUser = false;
	private boolean phoneHasBeenSetByUser = false;
	private JLabel lblfirstname;
	private JLabel lbllastname;
	private JLabel lblvisa;
	private JLabel lblbirthdate;
	private JLabel lblphone;
	private JLabel lblemail;

	public DTOContact getSelectedContact() {
		return selectedContact;
	}

	public void setSelectedContact(DTOContact selectedContact) {
		// if the user select a contact, update all fields on the frame
		this.selectedContact = selectedContact;
		refreshContact(selectedContact);
	}

	private JPanel contentPane;
	private JTextField txtlastname;
	private JTextField txtfirstname;
	private JTextField txtVisa;
	private JFormattedTextField txtPhone;
	private JTextField txtemail;
	private JTextField txtaddress;
	private JTextField txtlocality;
	private JTextField txtNPA;
	private JTable tblRelation;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		// class used to debug, can launch the form without using the main
		// application
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ContactManaging frame = new ContactManaging();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public ContactManaging() {
		this.setModal(true);
		// define the frame
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		this.setTitle("Ajout d'un nouveau contact");
		setBounds(100, 100, 593, 424);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		GridBagLayout gbl_contentPane = new GridBagLayout();
		gbl_contentPane.columnWidths = new int[] { 0, 0, 0, 0, 0 };
		gbl_contentPane.rowHeights = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
				0, 0, 0 };
		gbl_contentPane.columnWeights = new double[] { 0.0, 1.0, 0.0, 1.0,
				Double.MIN_VALUE };
		gbl_contentPane.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0,
				0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, Double.MIN_VALUE };
		contentPane.setLayout(gbl_contentPane);

		JPanel pnlSelect = new JPanel();
		GridBagConstraints gbc_pnlSelect = new GridBagConstraints();
		gbc_pnlSelect.gridwidth = 4;
		gbc_pnlSelect.insets = new Insets(0, 0, 5, 0);
		gbc_pnlSelect.fill = GridBagConstraints.BOTH;
		gbc_pnlSelect.gridx = 0;
		gbc_pnlSelect.gridy = 0;
		contentPane.add(pnlSelect, gbc_pnlSelect);
		pnlSelect.setLayout(new GridLayout(1, 0, 0, 0));

		JButton btnSelect = new JButton("Selectionner un contact");
		btnSelect.setName("btnSelect");
		btnSelect.addActionListener(this);
		pnlSelect.add(btnSelect);

		JButton btnNewContact = new JButton("Nouveau contact");
		btnNewContact.setName("btnNewContact");
		btnNewContact.addActionListener(this);
		pnlSelect.add(btnNewContact);

		JButton btnDelContact = new JButton("Supprimer un contact");
		btnDelContact.setName("btnDelContact");
		btnDelContact.addActionListener(this);
		pnlSelect.add(btnDelContact);

		lblCheck = new JLabel("Vérifier la validitée de vos données");
		lblCheck.setVisible(false);
		lblCheck.setFont(new Font("Tahoma", Font.BOLD, 11));
		lblCheck.setForeground(Color.RED);
		GridBagConstraints gbc_lblVrifierLaValidit = new GridBagConstraints();
		gbc_lblVrifierLaValidit.gridwidth = 4;
		gbc_lblVrifierLaValidit.insets = new Insets(0, 0, 5, 0);
		gbc_lblVrifierLaValidit.gridx = 0;
		gbc_lblVrifierLaValidit.gridy = 1;
		contentPane.add(lblCheck, gbc_lblVrifierLaValidit);

		lblsuccess = new JLabel("Les données ont été enregistrées avec succés");
		lblsuccess.setVisible(false);
		lblsuccess.setForeground(Color.GREEN);
		lblsuccess.setFont(new Font("Tahoma", Font.BOLD, 11));
		GridBagConstraints gbc_lblsuccess = new GridBagConstraints();
		gbc_lblsuccess.gridwidth = 4;
		gbc_lblsuccess.insets = new Insets(0, 0, 5, 0);
		gbc_lblsuccess.gridx = 0;
		gbc_lblsuccess.gridy = 2;
		contentPane.add(lblsuccess, gbc_lblsuccess);

		lbllastname = new JLabel("Nom* :");
		GridBagConstraints gbc_lblNom = new GridBagConstraints();
		gbc_lblNom.insets = new Insets(0, 0, 5, 5);
		gbc_lblNom.anchor = GridBagConstraints.EAST;
		gbc_lblNom.gridx = 0;
		gbc_lblNom.gridy = 3;
		contentPane.add(lbllastname, gbc_lblNom);

		txtlastname = new JTextField();
		txtlastname.getDocument().addDocumentListener(new DocumentListener() {

			@Override
			public void removeUpdate(DocumentEvent e) {
				autoVisa();

			}

			@Override
			public void insertUpdate(DocumentEvent e) {
				autoVisa();

			}

			@Override
			public void changedUpdate(DocumentEvent e) {
				autoVisa();

			}
		});
		GridBagConstraints gbc_txtlastname = new GridBagConstraints();
		gbc_txtlastname.insets = new Insets(0, 0, 5, 5);
		gbc_txtlastname.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtlastname.gridx = 1;
		gbc_txtlastname.gridy = 3;
		contentPane.add(txtlastname, gbc_txtlastname);
		txtlastname.setColumns(10);

		lblfirstname = new JLabel("Prénom* :");
		GridBagConstraints gbc_lblPrnom = new GridBagConstraints();
		gbc_lblPrnom.insets = new Insets(0, 0, 5, 5);
		gbc_lblPrnom.anchor = GridBagConstraints.EAST;
		gbc_lblPrnom.gridx = 2;
		gbc_lblPrnom.gridy = 3;
		contentPane.add(lblfirstname, gbc_lblPrnom);

		txtfirstname = new JTextField();
		txtfirstname.getDocument().addDocumentListener(new DocumentListener() {

			@Override
			public void removeUpdate(DocumentEvent e) {
				autoVisa();

			}

			@Override
			public void insertUpdate(DocumentEvent e) {
				autoVisa();

			}

			@Override
			public void changedUpdate(DocumentEvent e) {
				autoVisa();

			}
		});
		GridBagConstraints gbc_txtfirstname = new GridBagConstraints();
		gbc_txtfirstname.insets = new Insets(0, 0, 5, 0);
		gbc_txtfirstname.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtfirstname.gridx = 3;
		gbc_txtfirstname.gridy = 3;
		contentPane.add(txtfirstname, gbc_txtfirstname);
		txtfirstname.setColumns(10);

		lblvisa = new JLabel("Visa* :");
		GridBagConstraints gbc_lblVisa = new GridBagConstraints();
		gbc_lblVisa.anchor = GridBagConstraints.EAST;
		gbc_lblVisa.insets = new Insets(0, 0, 5, 5);
		gbc_lblVisa.gridx = 0;
		gbc_lblVisa.gridy = 4;
		contentPane.add(lblvisa, gbc_lblVisa);

		txtVisa = new JTextField();
		txtVisa.addFocusListener(new FocusListener() {

			@Override
			public void focusLost(FocusEvent e) {

			}

			@Override
			public void focusGained(FocusEvent e) {
				visaHasBeenSetByUser = true;
			}
		});
		GridBagConstraints gbc_txtVisa = new GridBagConstraints();
		gbc_txtVisa.insets = new Insets(0, 0, 5, 5);
		gbc_txtVisa.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtVisa.gridx = 1;
		gbc_txtVisa.gridy = 4;
		contentPane.add(txtVisa, gbc_txtVisa);
		txtVisa.setColumns(10);

		JLabel lblEntreprise = new JLabel("Entreprise :");
		GridBagConstraints gbc_lblEntreprise = new GridBagConstraints();
		gbc_lblEntreprise.insets = new Insets(0, 0, 5, 5);
		gbc_lblEntreprise.anchor = GridBagConstraints.EAST;
		gbc_lblEntreprise.gridx = 2;
		gbc_lblEntreprise.gridy = 4;
		contentPane.add(lblEntreprise, gbc_lblEntreprise);

		// load a list of company, add a company "null" at the start of the list
		ArrayList<DTOCompany> company = businessImpl.getAllCompany();
		company.add(0, new DTOCompany(0, "Ancune Entreprise", null, null, null,
				null, null, null, 0));
		Object[] cbxCompanyData = new Object[company.size()];

		for (int i = 1; i < company.size(); i++) {
			cbxCompanyData[i] = company.get(i);
		}

		cbxCompany = new JComboBox<Object>(cbxCompanyData);
		cbxCompany.setSelectedIndex(0);
		GridBagConstraints gbc_comboBox = new GridBagConstraints();
		gbc_comboBox.insets = new Insets(0, 0, 5, 0);
		gbc_comboBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_comboBox.gridx = 3;
		gbc_comboBox.gridy = 4;
		contentPane.add(cbxCompany, gbc_comboBox);

		lblbirthdate = new JLabel("Date de naissance* :");
		GridBagConstraints gbc_lblDateDeNaissance = new GridBagConstraints();
		gbc_lblDateDeNaissance.insets = new Insets(0, 0, 5, 5);
		gbc_lblDateDeNaissance.gridx = 0;
		gbc_lblDateDeNaissance.gridy = 5;
		contentPane.add(lblbirthdate, gbc_lblDateDeNaissance);

		// the date selector for the birthdate
		model = new UtilCalendarModel();
		JDatePanelImpl datePanel = new JDatePanelImpl(model);
		datePicker = new JDatePickerImpl(datePanel);
		datePicker.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				birthdate = (Calendar) datePicker.getModel().getValue();
			}
		});

		GridBagConstraints gbc_pnlDateSelection = new GridBagConstraints();
		gbc_pnlDateSelection.gridwidth = 3;
		gbc_pnlDateSelection.insets = new Insets(0, 0, 5, 0);
		gbc_pnlDateSelection.fill = GridBagConstraints.HORIZONTAL;
		gbc_pnlDateSelection.gridx = 1;
		gbc_pnlDateSelection.gridy = 5;
		contentPane.add(datePicker, gbc_pnlDateSelection);

		lblphone = new JLabel("Téléphone :");
		GridBagConstraints gbc_lblTlphone = new GridBagConstraints();
		gbc_lblTlphone.anchor = GridBagConstraints.EAST;
		gbc_lblTlphone.insets = new Insets(0, 0, 5, 5);
		gbc_lblTlphone.gridx = 0;
		gbc_lblTlphone.gridy = 6;
		contentPane.add(lblphone, gbc_lblTlphone);

		txtPhone = new JFormattedTextField(
				createFormatter("+41 (0)## ### ## ##"));
		txtPhone.setText("+41 (0)00 000 00 00");
		txtPhone.setForeground(Color.GRAY);
		txtPhone.addFocusListener(new FocusListener() {

			@Override
			public void focusLost(FocusEvent e) {

				txtPhone.setForeground(Color.BLACK);
			}

			@Override
			public void focusGained(FocusEvent e) {
				if (!visaHasBeenSetByUser) {
					txtPhone.setText("+41 (0)");
					txtPhone.setForeground(Color.BLACK);
					visaHasBeenSetByUser = true;
				}

			}
		});
		GridBagConstraints gbc_txtPhone = new GridBagConstraints();
		gbc_txtPhone.insets = new Insets(0, 0, 5, 5);
		gbc_txtPhone.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtPhone.gridx = 1;
		gbc_txtPhone.gridy = 6;
		contentPane.add(txtPhone, gbc_txtPhone);
		txtPhone.setColumns(10);

		lblemail = new JLabel("Email :");
		GridBagConstraints gbc_lblEmail = new GridBagConstraints();
		gbc_lblEmail.anchor = GridBagConstraints.EAST;
		gbc_lblEmail.insets = new Insets(0, 0, 5, 5);
		gbc_lblEmail.gridx = 2;
		gbc_lblEmail.gridy = 6;
		contentPane.add(lblemail, gbc_lblEmail);

		txtemail = new JTextField();
		txtemail.getDocument().addDocumentListener(new DocumentListener() {

			@Override
			public void removeUpdate(DocumentEvent e) {
				checkmail();

			}

			@Override
			public void insertUpdate(DocumentEvent e) {
				checkmail();

			}

			@Override
			public void changedUpdate(DocumentEvent e) {
				checkmail();

			}
		});
		GridBagConstraints gbc_txtemail = new GridBagConstraints();
		gbc_txtemail.insets = new Insets(0, 0, 5, 0);
		gbc_txtemail.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtemail.gridx = 3;
		gbc_txtemail.gridy = 6;
		contentPane.add(txtemail, gbc_txtemail);
		txtemail.setColumns(10);

		JLabel lblAdresse = new JLabel("Adresse :");
		GridBagConstraints gbc_lblAdresse = new GridBagConstraints();
		gbc_lblAdresse.anchor = GridBagConstraints.EAST;
		gbc_lblAdresse.insets = new Insets(0, 0, 5, 5);
		gbc_lblAdresse.gridx = 0;
		gbc_lblAdresse.gridy = 7;
		contentPane.add(lblAdresse, gbc_lblAdresse);

		txtaddress = new JTextField();
		GridBagConstraints gbc_txtaddress = new GridBagConstraints();
		gbc_txtaddress.anchor = GridBagConstraints.NORTH;
		gbc_txtaddress.insets = new Insets(0, 0, 5, 5);
		gbc_txtaddress.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtaddress.gridx = 1;
		gbc_txtaddress.gridy = 7;
		contentPane.add(txtaddress, gbc_txtaddress);
		txtaddress.setColumns(10);

		JLabel lblLocalit = new JLabel("Localité :");
		GridBagConstraints gbc_lblLocalit = new GridBagConstraints();
		gbc_lblLocalit.anchor = GridBagConstraints.EAST;
		gbc_lblLocalit.insets = new Insets(0, 0, 5, 5);
		gbc_lblLocalit.gridx = 0;
		gbc_lblLocalit.gridy = 8;
		contentPane.add(lblLocalit, gbc_lblLocalit);

		txtlocality = new JTextField();
		GridBagConstraints gbc_txtlocality = new GridBagConstraints();
		gbc_txtlocality.anchor = GridBagConstraints.NORTH;
		gbc_txtlocality.insets = new Insets(0, 0, 5, 5);
		gbc_txtlocality.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtlocality.gridx = 1;
		gbc_txtlocality.gridy = 8;
		contentPane.add(txtlocality, gbc_txtlocality);
		txtlocality.setColumns(10);

		JLabel lblNpa = new JLabel("NPA :");
		GridBagConstraints gbc_lblNpa = new GridBagConstraints();
		gbc_lblNpa.anchor = GridBagConstraints.EAST;
		gbc_lblNpa.insets = new Insets(0, 0, 5, 5);
		gbc_lblNpa.gridx = 2;
		gbc_lblNpa.gridy = 8;
		contentPane.add(lblNpa, gbc_lblNpa);

		txtNPA = new JTextField();
		GridBagConstraints gbc_txtNPA = new GridBagConstraints();
		gbc_txtNPA.insets = new Insets(0, 0, 5, 0);
		gbc_txtNPA.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtNPA.gridx = 3;
		gbc_txtNPA.gridy = 8;
		contentPane.add(txtNPA, gbc_txtNPA);
		txtNPA.setColumns(10);

		lblTypeofContact = new JLabel("Relation avec les classes :");
		GridBagConstraints gbc_lblTypeofContact = new GridBagConstraints();
		gbc_lblTypeofContact.anchor = GridBagConstraints.WEST;
		gbc_lblTypeofContact.insets = new Insets(0, 0, 5, 5);
		gbc_lblTypeofContact.gridx = 0;
		gbc_lblTypeofContact.gridy = 9;
		contentPane.add(lblTypeofContact, gbc_lblTypeofContact);

		ckbxTypeOfcontact = new JCheckBox("Enseignant :");
		ckbxTypeOfcontact.setHorizontalTextPosition(SwingConstants.LEFT);
		GridBagConstraints gbc_ckbxTypeOfcontact = new GridBagConstraints();
		gbc_ckbxTypeOfcontact.anchor = GridBagConstraints.SOUTH;
		gbc_ckbxTypeOfcontact.insets = new Insets(0, 0, 5, 5);
		gbc_ckbxTypeOfcontact.gridx = 1;
		gbc_ckbxTypeOfcontact.gridy = 9;
		contentPane.add(ckbxTypeOfcontact, gbc_ckbxTypeOfcontact);

		tblRelation = new JTable();
		GridBagConstraints gbc_tblRelation = new GridBagConstraints();
		gbc_tblRelation.gridwidth = 3;
		gbc_tblRelation.insets = new Insets(0, 0, 5, 5);
		gbc_tblRelation.fill = GridBagConstraints.BOTH;
		gbc_tblRelation.gridx = 0;
		gbc_tblRelation.gridy = 10;
		contentPane.add(new JScrollPane(tblRelation), gbc_tblRelation);

		JPanel panel = new JPanel();
		GridBagConstraints gbc_panel = new GridBagConstraints();
		gbc_panel.insets = new Insets(0, 0, 5, 0);
		gbc_panel.fill = GridBagConstraints.BOTH;
		gbc_panel.gridx = 3;
		gbc_panel.gridy = 10;
		contentPane.add(panel, gbc_panel);

		JButton btnAddRelation = new JButton("Ajouter");
		btnAddRelation.setName("btnAddRelation");
		btnAddRelation.addActionListener(this);
		panel.setLayout(new GridLayout(0, 1, 0, 0));
		panel.add(btnAddRelation);

		JButton btnDelRelation = new JButton("Supprimer");
		btnDelRelation.setName("btnDelRelation");
		btnDelRelation.addActionListener(this);
		panel.add(btnDelRelation);

		JPanel pnlCheck = new JPanel();
		GridBagConstraints gbc_pnlCheck = new GridBagConstraints();
		gbc_pnlCheck.gridwidth = 4;
		gbc_pnlCheck.fill = GridBagConstraints.BOTH;
		gbc_pnlCheck.gridx = 0;
		gbc_pnlCheck.gridy = 11;
		contentPane.add(pnlCheck, gbc_pnlCheck);
		pnlCheck.setLayout(new GridLayout(1, 0, 0, 0));

		JButton btnValidate = new JButton("Valider");
		btnValidate.setName("btnValidate");
		btnValidate.addActionListener(this);
		pnlCheck.add(btnValidate);

		JButton btnCancel = new JButton("Annuler");
		btnCancel.addActionListener(this);
		btnCancel.setName("btnCancel");
		pnlCheck.add(btnCancel);

		JButton btnFinish = new JButton("Terminer");
		btnFinish.setName("btnFinish");
		btnFinish.addActionListener(this);
		pnlCheck.add(btnFinish);
	}

	protected MaskFormatter createFormatter(String s) {
		MaskFormatter formatter = null;
		try {
			formatter = new MaskFormatter(s);
		} catch (java.text.ParseException exc) {
			System.err.println("formatter is bad: " + exc.getMessage());
			System.exit(-1);
		}
		return formatter;
	}

	public void autoVisa() {
		if (!visaHasBeenSetByUser) {
			int i = txtfirstname.getText().length();
			int j = txtlastname.getText().length();
			if (i > 3)
				i = 3;
			if (j > 3)
				j = 3;

			txtVisa.setText(txtfirstname.getText().subSequence(0, i)
					+ txtlastname.getText().substring(0, j));
		}

	}

	public void checkmail() {
		boolean at = false;
		boolean dot = false;

		for (int i = 0; i < txtemail.getText().length(); i++) {
			if (txtemail.getText().charAt(i) == '@')
				at = true;
			if (txtemail.getText().charAt(i) == '.')
				dot = true;

		}

		if (at && dot)
			lblemail.setForeground(Color.BLACK);
		else
			lblemail.setForeground(Color.RED);

	}

	/**
	 * Update a contact, if a contact is selcted, load each field, if not set
	 * each field to a null value to save a new contact
	 * 
	 * @param contact
	 */
	public void refreshContact(DTOContact contact) {
		if (contact != null) {

			this.setTitle("Modification de : " + contact);

			txtlastname.setText(contact.getLastname());
			txtfirstname.setText(contact.getFirstname());
			txtemail.setText(contact.getEmail());
			txtlocality.setText(contact.getLocality());
			txtaddress.setText(contact.getAddress());
			if (contact.getNpa() != 0)
				txtNPA.setText(Integer.toString(contact.getNpa()));
			else
				txtNPA.setText("");
			txtPhone.setText(contact.getPhone());
			txtVisa.setText(contact.getVisa());
			if (contact.getTypeOfContact() == 2) {
				ckbxTypeOfcontact.setSelected(true);
			} else {
				ckbxTypeOfcontact.setSelected(false);
			}

			Calendar cal = Calendar.getInstance();
			cal.setTime(contact.getBirthdate());
			model.setValue(cal);
			birthdate = cal;

			ArrayList<ArrayList<Object>> dataRelation = new ArrayList<ArrayList<Object>>();
			ArrayList<Object> temp = new ArrayList<Object>();
			DTOClass clasS = null;

			// load the relation to a class for a contact
			for (DTORelation dtoRelation : businessImpl
					.getAllRelationByContact(contact)) {
				clasS = businessImpl.getClassById(dtoRelation.getClass_id());
				if (clasS != null) {
					temp = new ArrayList<Object>();
					temp.add(clasS);
					temp.add(clasS.getName());
					temp.add(businessImpl.getContactById(clasS.getHolder_id()));
					dataRelation.add(temp);
				}

			}

			Object[][] relation;

			// update the table if there is some relation
			if (businessImpl.getAllRelationByContact(contact).size() != 0) {
				relation = new Object[dataRelation.size()][dataRelation.get(0)
						.size()];

				for (int i = 0; i < dataRelation.size(); i++) {
					for (int j = 0; j < dataRelation.get(i).size(); j++) {
						relation[i][j] = dataRelation.get(i).get(j);
					}
				}

				tblRelation.setModel(createModelTable(relation,
						Constant.CLASS_COLUMNNAMES));
				tblRelation.removeColumn(tblRelation.getColumnModel()
						.getColumn(0));
			} else
				tblRelation.setModel(createModelTable());

		} else {

			// Prepare to create a new contact
			this.setTitle("Ajout d'un nouveau contact");

			txtlastname.setText("");
			txtfirstname.setText("");
			txtemail.setText("");
			txtlocality.setText("");
			txtaddress.setText("");
			txtNPA.setText("");
			txtPhone.setText("");
			txtVisa.setText("");

			Calendar cal = Calendar.getInstance();
			model.setValue(cal);
			birthdate = cal;

			tblRelation.setModel(createModelTable());
		}

	}

	private boolean checkDataValidity() {
		boolean dataValid = true;
		// check the validity of the data before updating the database
		if (txtfirstname.getText().equals("")) {
			lblfirstname.setForeground(Color.RED);
			dataValid = false;
		} else {
			lblfirstname.setForeground(Color.BLACK);
		}
		if (txtlastname.getText().equals("")) {
			lbllastname.setForeground(Color.RED);
			dataValid = false;
		} else {
			lbllastname.setForeground(Color.BLACK);
		}
		if (txtVisa.getText().equals("")) {
			lblvisa.setForeground(Color.RED);
			dataValid = false;
		} else {
			lblvisa.setForeground(Color.BLACK);
		}
		if (birthdate == null) {
			lblbirthdate.setForeground(Color.RED);
			dataValid = false;
		} else {
			lblbirthdate.setForeground(Color.BLACK);
		}
		if (!txtNPA.getText().equals(""))
			try {
				Integer.parseInt(txtNPA.getText());
			} catch (NumberFormatException e) {
				dataValid = false;
			}
		else
			txtNPA.setText("0");
		if (lblemail.getForeground() == Color.RED)
			dataValid = false;
		return dataValid;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// event when the user click on a button, use the name of the source to
		// execute the right action
		if (e.getSource() instanceof JButton) {
			JButton source = (JButton) e.getSource();

			if (source.getName() == "btnSelect") {
				// when the user select a contact, open a JOptionPane with the
				// list of everycontact
				JFrame selectContact = new JFrame();
				Object[] object;

				ArrayList<DTOContact> possibilities = businessImpl
						.getAllContact();
				possibilities = businessImpl.sortContact(possibilities);

				object = new Object[possibilities.size()];

				for (int i = 0; i < possibilities.size(); i++) {
					object[i] = possibilities.get(i);

				}

				DTOContact contact = (DTOContact) JOptionPane.showInputDialog(
						selectContact, "Selectionner", "Selection",
						JOptionPane.OK_CANCEL_OPTION, null, object, 0);
				setSelectedContact(contact);

			}
			if (source.getName() == "btnNewContact") {
				// when the user want to add a new contact
				setSelectedContact(null);
			}
			if (source.getName() == "btnDelContact") {
				// if the user want to remove a contact, open a JOptionPanethen
				// require a confirmation from the user to remove the contact
				JFrame selectContact = new JFrame();
				Object[] object;

				ArrayList<DTOContact> possibilities = businessImpl
						.getAllContact();
				object = new Object[possibilities.size()];
				possibilities = businessImpl.sortContact(possibilities);
				for (int i = 0; i < possibilities.size(); i++) {
					object[i] = possibilities.get(i);

				}

				DTOContact contact = (DTOContact) JOptionPane.showInputDialog(
						selectContact, "Selectionner", "Selection",
						JOptionPane.OK_CANCEL_OPTION, null, object, 0);

				if (contact != null
						&& JOptionPane
								.showConfirmDialog(
										null,
										"Cette opération est irréversible, voulez-vous continuez ?",
										"Confirmer", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {

					businessImpl.removeContact(contact);

					if (contact.equals(selectedContact)) {
						setSelectedContact(null);
					}

				}
			}
			if (source.getName() == "btnValidate"
					|| source.getName() == "btnFinish") {
				// in case of a validation or a finish button, will check the
				// validity of the data then update the database
				if (checkDataValidity()) {
					if (selectedContact != null) {
						// if the contact already exist
						selectedContact.setFirstname(txtfirstname.getText());
						selectedContact.setLastname(txtlastname.getText());
						selectedContact.setVisa(txtVisa.getText());
						selectedContact.setBirthdate(birthdate.getTime());
						selectedContact.setAddress(txtaddress.getText());
						selectedContact.setEmail(txtemail.getText());
						selectedContact.setLocality(txtlocality.getText());
						selectedContact.setNpa(Integer.parseInt(txtNPA
								.getText()));
						selectedContact.setPhone(txtPhone.getText());
						if (ckbxTypeOfcontact.getSelectedObjects() != null)
							selectedContact.setTypeOfContact(2);
						else
							selectedContact.setTypeOfContact(1);
						selectedContact.setCompagny(0);

					} else {
						// if its a new contact
						int typeOfContact;
						if (ckbxTypeOfcontact.getSelectedObjects() != null)
							typeOfContact = 2;
						else
							typeOfContact = 1;

						int companyid;
						if (cbxCompany.getSelectedItem() == null)
							companyid = 0;
						else
							companyid = ((DTOCompany) cbxCompany
									.getSelectedItem()).getId();

						selectedContact = new DTOContact(0, companyid,
								txtlastname.getText(), txtfirstname.getText(),
								txtVisa.getText(), birthdate.getTime(),
								typeOfContact, txtPhone.getText(),
								txtemail.getText(), txtaddress.getText(),
								txtlocality.getText(), Integer.parseInt(txtNPA
										.getText()));
					}

					// get the an arraylist containing all related class to the
					// contact
					ArrayList<DTOClass> clasS = getArrayListDTOClass(tblRelation);

					// update the database
					businessImpl.updateContact(selectedContact, clasS);
					lblCheck.setVisible(false);
					lblsuccess.setVisible(true);
					this.setTitle("Modification de : " + selectedContact);
					selectedContact = businessImpl
							.getContactByVisa(selectedContact.getVisa());

				} else {
					// in case of fail
					lblCheck.setVisible(true);
					lblsuccess.setVisible(false);
				}
			}
			if (source.getName() == "btnAddRelation") {
				// action to add a class to the table, open an JOptionPane to
				// chose a class
				JFrame selectStudent = new JFrame();
				Object[] object;

				ArrayList<DTOClass> possibilities = businessImpl
						.getAllClassAvailable(selectedContact);
				if (possibilities != null) {
					possibilities = businessImpl.sortClass(possibilities);

					for (int i = 0; i < tblRelation.getModel().getRowCount(); i++) {
						for (int j = possibilities.size() - 1; j >= 0; j--) {
							DTOClass dtoClass = possibilities.get(j);
							if (tblRelation.getModel().getValueAt(i, 0)
									.equals(dtoClass))
								possibilities.remove(j);
						}
					}

					object = new Object[possibilities.size()];

					for (int i = 0; i < possibilities.size(); i++) {
						object[i] = possibilities.get(i);

					}

					DTOClass clasS = (DTOClass) JOptionPane.showInputDialog(
							selectStudent, "Selectionner", "Selection",
							JOptionPane.OK_CANCEL_OPTION, null, object, 0);
					if (clasS != null)
						addClassToTable(tblRelation, clasS);
				}
			}
			if (source.getName() == "btnDelRelation") {
				// remove the selected relation in the table
				if (tblRelation.getSelectedRow() > -1) {
					if (tblRelation.getModel().getValueAt(
							tblRelation.getSelectedRow(), 0) instanceof DTOClass) {
						removeTableSelectedRow(tblRelation);
					}

				}
			}
			if (source.getName() == "btnCancel") {
				// Dispose the frame is the user chose to cancel
				this.dispose();
			}
			if (source.getName() == "btnFinish") {
				// if the data are valid, close the dispose the fram
				if (checkDataValidity())
					this.dispose();
				else
					lblCheck.setVisible(true);
				lblsuccess.setVisible(false);
			}
		}
	}

	private void addClassToTable(JTable table, DTOClass clasS) {
		// add to the tblClass the selected class
		DefaultTableModel dtm = (DefaultTableModel) table.getModel();
		int nRow = dtm.getRowCount();
		Object[][] tableData = new Object[nRow + 1][3];
		for (int i = 0; i < nRow; i++)
			for (int j = 0; j < 3; j++)
				tableData[i][j] = dtm.getValueAt(i, j);

		tableData[nRow][0] = clasS;
		tableData[nRow][1] = clasS.getName();
		tableData[nRow][2] = businessImpl.getContactById(clasS.getHolder_id());

		table.setModel(createModelTable(tableData, Constant.CLASS_COLUMNNAMES));
		table.removeColumn(table.getColumnModel().getColumn(0));
		table.repaint();
	}

	private DefaultTableModel createModelTable(Object[][] tableData,
			Object[] columnNames) {
		// Create the defaultTableModel with the data for the table containing
		// classes
		DefaultTableModel dtm = new DefaultTableModel(tableData, columnNames) {

			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@Override
			public boolean isCellEditable(int row, int column) {
				// all cells false
				return false;
			}

		};

		return dtm;
	}

	private DefaultTableModel createModelTable() {
		// is there is no class related to a contact, create an empty table
		DefaultTableModel dtm = new DefaultTableModel();
		return dtm;

	}

	private void removeTableSelectedRow(JTable table) {
		// remove the selected row from a table
		DefaultTableModel dtm = (DefaultTableModel) table.getModel();
		dtm.removeRow(table.getSelectedRow());
		table.setModel(dtm);
	}

	private ArrayList<DTOClass> getArrayListDTOClass(JTable table) {
		// return into and arrayList of class the data into the table
		DefaultTableModel dtm = (DefaultTableModel) table.getModel();
		ArrayList<DTOClass> ret = new ArrayList<DTOClass>();
		int nRow = dtm.getRowCount();

		for (int i = 0; i < nRow; i++)
			ret.add((DTOClass) dtm.getValueAt(i, 0));

		return ret;
	}
}
